#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>

#define NUM 10
typedef void (*func_t)();//函数指针

func_t handlerTask[NUM];

//样例任务
void task1()
{
    printf("handler task1\n");
}
void task2()
{
    printf("handler task2\n");
}
void task3()
{
    printf("handler task3\n");
}
void task4()
{
    printf("handler task4\n");
}

void addtask()
{}

void loadtask()
{
    memset(handlerTask,0,sizeof(handlerTask));
    handlerTask[0]=task1;
    handlerTask[1]=task2;
    handlerTask[2]=task3;
}



int main()
{
    pid_t id = fork();
    assert(id!=-1);
    if(id==0)
    {
        //child
        int cnt = 10;
        while(cnt)
        {
            printf("child running,pid:%d,ppid:%d,cnt:%d\n",getpid(),getppid(),cnt--);
            sleep(3);
            //int* p=0;
            //*p=100;//野指针
        }
        exit(10);
    }
    //------------非阻塞等待-----------
    int status = 0;
    loadtask();
    while(1)
    {
        pid_t ret=waitpid(id,&status,WNOHANG);//WNOHANG:--> 非阻塞，子进程没有退出，父进程检测的时候，立即返回
        if(ret==0)
        {
            //waitpid调用成功 && 子进程没有退出
            //子进程没有退出，waitpid没有检测失败，仅仅是检测到了子进程没有退出
            printf("wait done! but child is running...\n");
            //printf("wait done! but child is running..., parent running other things\n");
            for(int i=0;handlerTask[i]!=NULL;i++)
            {
                handlerTask[i]();
            }
            
        }
        else if(ret>0)//ret==id
        {
            //waitpid调用成功 && 子进程退出了
            printf("wait success! exit code: %d, sig: %d\n",(status>>8)&0xFF,status & 0x7F);
            break;
        }
        else{
            //waitpid调用失败
            printf("waitpid call failed!\n");
            break;
        }
        sleep(1);
    }





    //------------阻塞等待-------------

    //parent
    //1、让OS释放子进程的僵尸状态
    //2、获取子进程的退出结果
    //在等待期间，子进程没有退出的时候，父进程只能阻塞等待
     // int status=0;
     // int ret = waitpid(id,&status,0);//0-->阻塞等待
     // if(ret>0)
     // {
     //     //是否正常退出
     //     if(WIFEXITED(status))
     //     {
     //         //判断子进程结果是否正确
     //         printf("exit code:%d\n",WEXITSTATUS(status));
     //     }
     //     else{
     //         //TODO
     //       printf("child exit not normal!\n");
     //     }
     //     //printf("wait sucess! child exit code:%d,sig:%d\n",(status>>8)&0xFF,status & 0x7F);
     // }

     // return 0;
}
